package com.ruoyi.framework.config

import com.ruoyi.common.utils.Threads.printException
import org.apache.commons.lang3.concurrent.BasicThreadFactory
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor
import java.util.concurrent.ScheduledExecutorService
import java.util.concurrent.ScheduledThreadPoolExecutor
import java.util.concurrent.ThreadPoolExecutor

/**
 * 线程池配置
 *
 * @author ruoyi
 */
@Configuration
open class ThreadPoolConfig {
    // 核心线程池大小
    private val corePoolSize = 50

    // 最大可创建的线程数
    private val maxPoolSize = 200

    // 队列最大长度
    private val queueCapacity = 1000

    // 线程池维护线程所允许的空闲时间
    private val keepAliveSeconds = 300
    @Bean(name = ["threadPoolTaskExecutor"])
    open fun threadPoolTaskExecutor(): ThreadPoolTaskExecutor {
        val executor = ThreadPoolTaskExecutor()
        executor.maxPoolSize = maxPoolSize
        executor.corePoolSize = corePoolSize
        executor.queueCapacity = queueCapacity
        executor.keepAliveSeconds = keepAliveSeconds
        // 线程池对拒绝任务(无线程可用)的处理策略
        executor.setRejectedExecutionHandler(ThreadPoolExecutor.CallerRunsPolicy())
        return executor
    }

    /**
     * 执行周期性或定时任务
     */
    @Bean(name = ["scheduledExecutorService"])
    protected open fun scheduledExecutorService(): ScheduledExecutorService {
        return object : ScheduledThreadPoolExecutor(corePoolSize,
                BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build(),
                CallerRunsPolicy()) {
            override fun afterExecute(r: Runnable, t: Throwable?) {
                super.afterExecute(r, t)
                printException(r, t)
            }
        }
    }
}
